package javaapplication3;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.awt.*;
public class JavaApplication3 extends JApplet {
  JLabel Title;
  CustomCanvas DrawingArea;
  public JavaApplication3 () 
  {
    Container Pane;
    Pane = getContentPane();
    Title = new JLabel ("You Work is Done");
    DrawingArea = new CustomCanvas();
    Pane.add (Title, BorderLayout.SOUTH);
    Pane.add (DrawingArea, BorderLayout.CENTER);
  }
}
class CustomCanvas extends Canvas 
{
    public static double n;
    public static String stra;
    public static boolean qw = true;
    public static double max;
    public static double max1;
    public static double min1;
    public static double min;
    public static double x1;
    public static double x2;
    public static int stroka;
    public static double an [] [];
    private static int c = -2;
  public CustomCanvas () 
  {
    setBackground (Color.white);
  }
    @Override
  public void paint (Graphics g) {
      Graphics2D g2;
      int Height = getHeight();
      int Width = getWidth ();
      g2 = (Graphics2D) g;
      if (qw == true)
      {
        try {
            Read1 ();
        } catch (IOException ex) {
            Logger.getLogger(CustomCanvas.class.getName()).log(Level.SEVERE, null, ex);
        }
        qw = false;
      }
      int step = Size (Width, Height);
      int q = 15;
      double e = x1;
      while (q < Width+step)
      {
         g2.setColor(Color.red);
         g2.drawLine(q, Height, q, 0);
         g2.setColor(Color.BLACK);
         g2.drawString(Double.toString((double)((int)(e*100))/100),q,15);
         e = e + step*(1/n);
         q = q+step;
      }
      q = 15;
      e = max1;
      while (q < Height+step)
      {
         g2.setColor(Color.red);
         g2.drawLine(Width, q, 0, q);
         g2.setColor(Color.BLACK);
         g2.drawString(Double.toString((double)((int)(e*100))/100),0,q);
         e = e - step*(1/n);
         q = q+step;
      }
      Build (g,(x2-x1)/(Width-30), Width, Height);
  }
  public static int Size (int w, int h)
  {
      double s = (x2-x1)/(w-30);
      boolean c = true;
      double a = x1;
      while (a < x2+s)
      {
          if (StringEquals (Count (a), "!") == false)
          {
              Ext (Double.valueOf(Count (a)), c);
              c = false;
          }
          a = a+s;
      }
      int v = 0;
      String strarr [] = stra.split(" ");
      int d = Integer.valueOf(strarr [0]);
      if (d > 6 && d != 9)
      {
          if ((w-30)/(x2-x1) > (h-30)/(max-min))
          {
              v = (h-30)/15;
              n = (h-30)/(max-min);
              max1 = max;
              min1 = min;
              x2 = (x2-x1)/2+x1+(w-30)/n/2;
              x1 = (x2-x1)/2+x1-(w-30)/n/2;
          }
          else
          {
              v = (w-30)/30;
              n = (w-30)/(x2-x1);
              max1 = (max-min)/2+min+(h-30)/2/n;
              min1 = max1 - (h-30)/n;
          }
      }
      if (d < 7 || d == 9)
      {
      double b = Double.valueOf(strarr [1]);
      v = (w-30)/30;
      n = (w-30)/(x2-x1);
      max1 = (max-min)/2+min+(h-30)/2/n;
      min1 = max1 - (h-30)/n;
      if (d == 4)
      {
          min1 = Double.valueOf(strarr [4])*b;
          max1 = (h-30)/n+min1;
      }
      if (d == 3)
      {
          min1 = Double.valueOf(strarr [4])*b - (h-30)/n/2;
          max1 = Double.valueOf(strarr [4])*b + (h-30)/n/2;
      }
          if (d == 2 || d == 5)
          {
             if (b > 0)
             {
                 max1 = (h-30)/n+min;
                 min1 = min;
             }
             else
             {
                 min1 = max - (h-30)/n;
                 max1 = max;
             }
          }
      }
      return v;
  }
   private static String Count (double x)
  {
      String a = "!";
      String [] st = stra.split(" ");
      int s = Integer.valueOf(st [0]);
      if (s == 1)
      {
          a = Double.toString(Double.valueOf(st [1])*x+Double.valueOf(st[2]));
      }
      if (s == 2)
      {
          a = Double.toString(Double.valueOf(st [1])*x*x+Double.valueOf(st[2])*x+Double.valueOf(st [3]));
      }
      if (s == 5)
      {
              double w = -Double.valueOf(st [3])/Double.valueOf(st [2]);
              if ((Double.valueOf(st [2]) > 0 && x >= w) || (Double.valueOf(st [2]) < 0 && x <= w))
              {
                  a = Double.toString(Double.valueOf(st [1])*(Math.sqrt(Double.valueOf(st [2])*x+Double.valueOf(st [3]))+Double.valueOf(st [4])));
              }
      }
      if (s == 6)
      {
          double r = -Double.valueOf(st [3])/Double.valueOf(st [2]);
          if (x != r)
          {
              a = Double.toString(Double.valueOf(st [1])*(1/(Double.valueOf(st [2])*x+Double.valueOf(st [3])) +Double.valueOf(st [4])));
          }
      }
      if (s == 4)
      {
          a = Double.toString(Double.valueOf (st [1])*(Math.pow(Double.valueOf(st [5]), Double.valueOf(st[2])*x+Double.valueOf(st [3]))+Double.valueOf(st [4])));
      }
      if (s == 3)
      {
          double t = Double.valueOf(st[2])*x+Double.valueOf(st [3]);
          if (t > 0)
          {
            a = Double.toString(Double.valueOf(st [1])*(1/Math.log(Double.valueOf(st [5]))*Math.log(t)+Double.valueOf (st[4])));
          }
      }
      if (s == 7)
      {
          a = Double.toString(Double.valueOf(st [1])*(Math.sin(x*Double.valueOf(st [2])+Double.valueOf(st [3]))+Double.valueOf(st [4])));
      }
      if (s == 8)
      {
          a = Double.toString(Double.valueOf(st [1])*(Math.cos(x*Double.valueOf(st [2])+Double.valueOf(st [3]))+Double.valueOf(st [4])));
      }
      if (s == 9)
      {
          double p = x*Double.valueOf(st [2])+Double.valueOf(st [3]);
          if (Double.isInfinite(p) == false)
          {
              a = Double.toString(Double.valueOf(st [1])*(Math.tan(p)+Double.valueOf(st [4])));   
          }
      }
      if (s == 10)
      {
          double p = x*Double.valueOf(st [2])+Double.valueOf(st [3]);
          if (Math.abs(p) <= 1)
          {
              a = Double.toString(Double.valueOf(st [1])*(Math.asin(p)+Double.valueOf(st [4])));   
          }
      }
      if (s == 11)
      {
          double p = x*Double.valueOf(st [2])+Double.valueOf(st [3]);
          if (Math.abs(p) <= 1)
          {
              a = Double.toString(Double.valueOf(st [1])*(Math.acos(p)+Double.valueOf(st [4])));   
          }
      }
      if (s == 12)
      {
              a = Double.toString(Double.valueOf(st [1])*(Math.atan(x*Double.valueOf(st [2])+Double.valueOf(st [3]))+Double.valueOf(st [4])));   
      }
      return a;
  }
  public static void Ext (double y, boolean c)
  {
      if (c == true)
      {
          max = y;
          min = y;
      }
      else
      {
          if (y > max)
          {
              max = y;
          }
          if (min > y)
          {
              min = y;
          }
      }
  }
  private static void Read1 () throws IOException
  {
      BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));
      String [] arr = new String [12];
      arr [0] = "line";
      arr [1] = "sqr";
      arr [4] = "sqrt";
      arr [5] = "hyp";
      arr [2] = "log";
      arr [3] = "pow";
      arr [6] = "sin";
      arr [7] = "cos";
      arr [8] = "tg";
      arr [9] = "asin";
      arr [10] = "acos";
      arr [11] = "atg";
      int a = 0;
      System.out.println ("Задайте значения x1 и x2(x1 < x2) (через пробел)");
      String str2 = reader.readLine();
      String [] str = str2.split(" ");
      x1 = Double.valueOf(str [0]);
      x2 = Double.valueOf(str [1]);
      while (a == 0)
      {
      System.out.println("Выберите функцию которую хотите построить");
      System.out.println("line - Линейная функция");
      System.out.println("sqr - Квадратный трёхчлен");
      System.out.println("log - Функция вида k*((log по а от (l*b+d))+f)");
      System.out.println ("pow - Функция вида k*(a^(l*x+d)+f)");
      System.out.println ("sqrt - Функция вида k*((l*x+d)^1/2+f)");
      System.out.println ("hyp - Функция вида k*(1/(l*x+d)+f)");
      System.out.println ("sin - Функция вида k*(sin(l*x+d)+f)");
      System.out.println ("cos - Функция вида k*(cos(l*x+d)+f)");
      System.out.println ("tg - Функция вида k*(tg(l*x+d)+f)");
      System.out.println ("asin - Функция вида k*(arcsin(l*x+d)+f)");
      System.out.println ("acos - Функция вида k*(arccos(l*x+d)+f)");
      System.out.println ("atg - Функция вида k*(arctg(l*x+d)+f)");
      String str1 = reader.readLine();
          for (int i = 0; i < arr.length; i++)
          {
              if (StringEquals(str1,arr [i]) == true)
              {
                  a = i+1;
              }
          }
      }
      String str1 = "";
      if (a == 1)
      {
          System.out.println ("Задайте значения k,d (через пробел)");
          str1 = reader.readLine();
          stra = "1 "+str1;
      }
      if (a == 2)
      {
          System.out.println ("Задайте значения a,b,c (через пробел)");
          str1 = reader.readLine();
          stra = "2 "+str1;
      }
      if (a > 2 && a < 5)
      {
          System.out.println ("Задайте значения k,l,d,f,a (через пробел)");
          str1 = reader.readLine();
          stra = Integer.toString(a)+" "+str1;
      }
      if (a > 4)
      {
          System.out.println ("Задайте значения k,l,d,f (через пробел)");
          str1 = reader.readLine();
          stra = Integer.toString(a)+" "+str1;
      }
       System.out.println("Thank You for Using our programm");
  }
    private static boolean StringEquals (String str1,String str2)
    {
        boolean eq = false;
        char [] charr1 = str1.toCharArray();
        char [] charr2 = str2.toCharArray();
        int q = 0;
        int w = 0;
        if (charr2.length == charr1 .length)
        {
            while (q < charr1.length)
            {
                if (charr1[q] == charr2 [q])
                {
                    w++;
                }
                q++;
            }
            if (w == charr1.length)
            {
                eq = true;
            }
        }
        return eq;
    }
    private static void Build (Graphics g,double s,int w,int h)
  {
      g.setColor(Color.BLUE);
      boolean m = true;  
      for (int q = 1; q < w; q = q+1)
      {
          double xm1 = (q-15)/n+x1;
          double xm2 = (q-16)/n+x1;
          String y1 = Count (xm1);
          String y2 = Count (xm2);
          if (StringEquals (y1, "!") == false && StringEquals (y2, "!") == false)
          {
            g.drawLine((int)((xm2-x1)*n+15),(int)(h - 15 - (Double.valueOf(y2)-min1)*n),(int)((xm1-x1)*n+15),(int)(h - 15 -(Double.valueOf(y1)-min1)*n));
          }
      }
  }
    public static void Formula (String str1, int a, int b)
    {
        String [] st = new String [16];
        st [0] = "+";
        st [1] = "-";
        st [2] = "*";
        st [3] = "/";
        st [4] = "^";
        st [8] = "sin";
        st [9] = "cos";
        st [7] = "tg";
        st [10] = "ctg";
        st [15] = "arcsin";
        st [13] = "arccos";
        st [12] = "arctg";
        st [14] = "arcctg";
        st [11] = "log";
        st [5] = "(";
        st [6] = ")";//приоритеты... Сначала скобки потом всё остальное
        String [] arr = str1.split("");
        int q = a-1;
        int w = 0;
        int u = 0;
        double n = 0;
        if (b == -1)
        {
            b = arr.length;
        }
    }
            private static double Count (int begin, int end)
        {
            int res = 0;
            double n = 0;
          //  for (int i = ; i < stroka; i++)
          //  {
             //   if (an [16] [i] == 1)
             //   {
               //     an [17] [i] = a;
             //   }
           // }
            int q = begin;
            while (q < end+1)
            {
                if (an [5] [q] == 1 && an [18] [q] == 0)
                {
                    int a = q+1;
                    int e = q+1;
                    int w = 1;
                    while (w != 0)
                    {
                        if (an [5] [e] == 1)
                        {
                            w++;
                        }
                        if (an [6] [e] == 1)
                        {
                            w--;
                        }
                        e++;
                    }
                    an [17] [a-1] = Count (a,e-1);
                    an [18] [a-1] = c;
                    an [18] [e-1] = c;
                    c--;
                    for (int m = a; m < e-1; m++)
                    {
                        an [18] [m] = 1;
                    }
                }
                q++;
            }
            q = begin;
            while (q < end+1)
            {
                int s = 7;
                while (s < 16)
                {
                    if (an [s] [q] == 1)
                    {
                        an [17] [q] = calc (s, an [17] [q+1]);
                        an [18] [q] = 1;
                        an [18] [q] = 1;
                        res = q;
                    }
                    s++;
                }
                q++;
            }
            if (check () == false)
            {
                q = begin;
                while (q < end+1)
                {
                    if (an [4] [q] == 1)
                    {
                        if (an [6] [q-1] == 0)
                        {
                            an [17] [q] = Math.pow(an [17] [q-1],an [17] [q+1]);
                            an [18] [q] = 2;
                        }
                        else
                        {
                            int z = 0;
                            for (int i = 0; i < end; i++)
                            {
                                if (an [18] [q-1] == an [18] [i])
                                {
                                    z = i;
                                    break;
                                }
                            }
                            an [17] [q] = Math.pow(an [17] [z], an [17] [q+1]);
                            an [18] [q] = 1;
                            res = q;
                        }
                    }
                    q++;
                }
            }
            if (check () == false)
            {
                q = begin;
                while (q < end+1)
                {
                    if (an [3] [q] == 1 || an [2] [q] == 1)
                    {
                        if (an [6] [q-1] == 0)
                        {
                            if (an [2] [q] == 1)
                            {
                                an [17] [q] = an [17] [q-1] * an [17] [q+1];
                            }
                            else
                            {
                                an [17] [q] = an [17] [q-1] / an [17] [q+1];
                            }
                            an [18] [q] = 1;
                            res = q;
                        }
                        else
                        {
                            int z = 0;
                            for (int i = 0; i < end; i++)
                            {
                                if (an [18] [q-1] == an [18] [i])
                                {
                                    z = i;
                                    break;
                                }
                            }
                            if (an [2] [q] == 1)
                            {
                                an [17] [q] = an [17] [z] * an [17] [q+1];
                            }
                            else
                            {
                                an [17] [q] = an [17] [z] / an [17] [q+1];
                            }
                            an [18] [q] = 1;
                            res = q;
                        }
                    }
                    q++;
                }
            }
            if (check () == false)
            {
                q = begin;
                while (q < end+1)
                {
                    if (an [1] [q] == 1 || an [0] [q] == 1)
                    {
                        if (an [6] [q-1] == 0)
                        {
                            if (an [0] [q] == 1)
                            {
                                an [17] [q] = an [17] [q-1] + an [17] [q+1];
                            }
                            else
                            {
                                an [17] [q] = an [17] [q-1] - an [17] [q+1];
                            }
                            an [18] [q] = 1;
                            res = q;
                        }
                        else
                        {
                            int z = 0;
                            for (int i = 0; i < end; i++)
                            {
                                if (an [18] [q-1] == an [18] [i])
                                {
                                    z = i;
                                    break;
                                }
                            }
                            if (an [0] [q] == 1)
                            {
                                an [17] [q] = an [17] [z] + an [17] [q+1];
                            }
                            else
                            {
                                an [17] [q] = an [17] [z] - an [17] [q+1];
                            }
                            an [18] [q] = 1;
                            res = q;
                        }
                    }
                    q++;
                }
            }
            if (check () == false)
            {
                n = an [17] [begin+1];
            }
            if (check () == true)
            {
                n = an [17] [res];
            }
            return n;
        }
        private static double calc (int s, double a)
        {
            double b = 0;
            if (s == 7)
            {
                b = Math.tan(a);
            }
            if (s == 8)
            {
                b = Math.sin(a);
            }
            if (s == 9)
            {
                b = Math.cos(a);
            }
            if (s == 10)
            {
                b = 1/Math.tan(a);
            }
            if (s == 11)
            {
                b = Math.log(a);
            }
            if (s == 12)
            {
                b = Math.atan(a);
            }
            if (s == 13)
            {
                b = Math.acos(a);
            }
            if (s == 14)
            {
                b = -Math.tan(a)+Math.PI/2;
            }
            if (s == 15)
            {
                b = Math.asin(a);
            }
            return b;
        }
        private static boolean check ()
        {
            boolean a = true;
            for (int i = 0; i < stroka; i++)
            {
                if (an [18] [i] == 0)
                {
                    a = false;
                    break;
                }
            }
            return a;
        }
}